Skip to main content

Keyword Route

What does it do?

Routes to different nodes based on regex matches against the user's last message. Checks the last message text — including text messages, media captions, and postback payloads — and routes according to the last pattern that matches (see Match order).

What is tested: the full text of the last inbound message (or caption / postback payload). The pattern must match somewhere in that string unless you use anchors (^ / $) to require the whole line to look a certain way.


1. Syntax

  <node_name>:
type: func
func_type: system
func_id: keywordsRoute
params:
<target_node_1>: "<regex pattern>"
<target_node_2>: "<regex pattern>"
on_complete: <fallback_node>

Always wrap patterns in double quotes "..." so characters like |, :, or * are not parsed as YAML syntax.

required params

  • type type of the node
  • func_type here it will be a system function
  • func_id what function are we calling (keywordsRoute)
  • params key-value pairs where each key is a destination node name and each value is a regex pattern to test against the last message
  • on_complete node to go to if no pattern matches

optional params

  • department assigns the chat to a department
  • agent assigns the chat to a specific agent (email address or CRM ID as defined in the Texter agents manager)

Match order

Patterns are evaluated in params key order (the order keys appear in the YAML). Each time a pattern matches, the destination node is updated — so if more than one pattern matches the same message, the last matching entry wins. Put broader / catch-all patterns first and more specific routes later if you want the specific route to take priority when both could match.

Regex reference (JavaScript RegExp)

Patterns are passed to new RegExp(yourPattern) (no extra flags). Matching is case-sensitive unless you build that into the pattern (e.g. [Ss]ales or (sales|Sales)).

ConstructMeaning
^Start of the string
$End of the string
\bWord boundary (between word and non-word char)
.Any single character (except newline)
*Previous token: zero or more
+Previous token: one or more
?Previous token: zero or one (also makes +/* non-greedy)
Pipe (see note)Alternation — match left or right side of `
[abc]One character from the set
[^abc]One character not in the set
[0-9] \dDigit
\wWord character (letter, digit, _)
\sWhitespace
{n} {n,} {n,m}Exact / at least / between min and max repetitions
()Capturing group (here only the pattern matters for .test())
\Escape special chars — e.g. \. for a literal dot
tip

In regex, alternation is the pipe character (e.g. sales|buy). In YAML, quote the whole pattern ("sales|buy") so | is not treated as special YAML syntax.

tip

Invalid regex strings are caught; the error is logged and that pattern is skipped — avoid typos in complex patterns.


2. Examples

Basic keyword routing

What it checks: the last message contains the substring sales or buy or purchase or pricing anywhere (same for the other lines). Not whole words unless you add \b (see below).

  check_keywords:
type: func
func_type: system
func_id: keywordsRoute
params:
sales_menu: "sales|buy|purchase|pricing"
support_menu: "help|support|issue|problem"
billing_menu: "bill|invoice|payment"
on_complete: main_menu

Detect a specific phrase at bot start

What it checks: the last message contains that exact Hebrew phrase as a substring anywhere (e.g. user pasted a longer sentence that includes it). For a full-line-only match you would add ^ at the start and $ at the end inside the quotes.

  start:
type: func
func_type: system
func_id: keywordsRoute
params:
noop_handoff: "היי, אשמח לדבר עם נציגה מהסניף"
on_complete: store_initial_customer_details

Instagram/Facebook welcome routing

What it checks: last message contains instagram, ig, or insta (first row), or facebook / fb (second row), as substrings.

  instagram_welcome:
type: func
func_type: system
func_id: keywordsRoute
params:
instagram_menu: "instagram|ig|insta"
facebook_menu: "facebook|fb"
on_complete: general_welcome

Keywords as first-message filter (template replies)

What it checks: same idea — substrings like interested, details, or info (marketing), or appointment / schedule / book (appointment flow).

  check_keywords_from_template:
type: func
func_type: system
func_id: keywordsRoute
params:
marketing_flow: "interested|details|info"
appointment_flow: "appointment|schedule|book"
on_complete: main_menu

Regex: digits-only message OR greeting at the start

What it checks:

  • order_flow: the entire last message is only digits, and at least 5 digits (^$ = full string). Examples that match: 12345, 999999. No letters or spaces.
  • greeting_flow: the message starts with the word hi, hello, or hey (after ^), followed by a word boundary (\b) so high does not match hi.
  check_order_number:
type: func
func_type: system
func_id: keywordsRoute
params:
order_flow: "^[0-9]{5,}$"
greeting_flow: "^(hi|hello|hey)\\b"
on_complete: main_menu

Whole words only (not inside longer words)

What it checks: the last message contains yes, כן, or ok as whole words (\b = boundary between “word” and non-word characters). So yes please matches; eyes does not match yes as a whole word.

  word_only:
type: func
func_type: system
func_id: keywordsRoute
params:
yes_flow: "\\b(yes|כן|ok)\\b"
on_complete: ask_again

Phone-like digit sequence (Israeli mobile style)

What it checks: last message contains something that looks like an Israeli mobile number: optional +972 or 0, then digit 5, then 8 more digits (9 digits total for the local part). Used to detect if the user pasted a phone in the message.

  phone_hint:
type: func
func_type: system
func_id: keywordsRoute
params:
has_phone: "(\\+?972|0)?[5][0-9]{8}"
on_complete: no_phone

Case variants (no case-insensitive flag)

What it checks: substring Sales or sales (first letter either case) or Buy or buy.

  case_sales:
type: func
func_type: system
func_id: keywordsRoute
params:
sales_menu: "[Ss]ales|[Bb]uy"
on_complete: main_menu

Match order: broader first, specific last (last match wins)

What it checks: if the user writes something like urgent help, both patterns match (contains help and urgent). Because urgent_escalation is listed second, that node wins. If they only write help, only the first pattern matches.

  triage:
type: func
func_type: system
func_id: keywordsRoute
params:
generic_help: "help|support|problem"
urgent_escalation: "urgent|asap|emergency"
on_complete: main_menu
tip

Values are regex patterns. Use double quotes "..." for every pattern so |, :, *, ^, and \ behave correctly in YAML.

info

The last message text is sourced from text messages, media captions, and postback payloads. Params are tested in YAML key order; each match overwrites the previous, so when several patterns match, the last matching pattern’s node is used — not the first.